<template>
	<view class="dynamicForm">
		<up-form :model="form" ref="uFormRef" :rules="rules" border labelPosition="left" labelWidth="auto">
			<template v-for="(item,index) in formFields" :key='index'>
				<up-form-item :prop="item.name" borderBottom>
					<template #label>
						<text>{{item.label}}</text>
						<text style="color: red" v-if="item.required">*</text>
					</template>

					<template #right>
						<view v-if="item.type==='TEXT'">
							<up-input v-model="form[item.name]" border="none" input-align="right" fontSize="13px"
								:placeholder="item.placeholder" />
						</view>
						<view v-if="item.type==='SELECT'">
							<uni-data-select v-model="form[item.name]" placement='bottom' :placeholder="item.placeholder"
								:localdata="item.options.options" class="uniDataSelectStyle" @change="(val)=>{
									changeSelect(val,item)
								} "></uni-data-select>
						</view>
						<view v-if="item.type==='CASCADER'">
							<uni-data-picker v-model="form[item.name]" :placeholder="item.placeholder"
								:localdata="item.options.options" class="uniDataPickerStyle" @change='(val)=>{
									changePicker(val,item.name)
								} '></uni-data-picker>
						</view>
						<view v-if="item.type==='TEXTAREA'">
							<up-textarea v-model="form[item.name]" border="none" input-align="right" fontSize="13px"
								:placeholder="item.placeholder" style="width: 200px;" count />
						</view>
						<view v-if="item.type==='DATE'">
							<uni-datetime-picker v-model="form[item.name]" :border="false" />
						</view>
					</template>
				</up-form-item>
				<template v-if="item.type==='NESTTEXT'">
					<template v-for="(itemN,indexN) in item.nestField" :key="indexN">
						<up-form-item v-for="(itemC,indexC) in itemN" :key="indexC" :prop="itemC.name" borderBottom>
							<template #label>
								<text>{{itemC.label}}</text>
								<text style="color: red" v-if="itemC.required">*</text>
							</template>

							<template #right>
								<view v-if="itemC.type==='TEXT'">
									<up-input v-model="form[itemC.name]" border="none" input-align="right" fontSize="13px"
										:placeholder="itemC.placeholder" @blur="(value)=>{
											blurFun(itemN,index,indexC,indexN,value)
										}" />
								</view>
								<view v-if="itemC.type==='SELECT'">
									<uni-data-select v-model="form[itemC.name]" placement='bottom' :placeholder="itemC.placeholder"
										:localdata="itemC.options.options" class="uniDataSelectStyle"></uni-data-select>
								</view>
								<view v-if="itemC.type==='CASCADER'">
									<uni-data-picker v-model="form[itemC.name]" :placeholder="itemC.placeholder"
										:localdata="itemC.options.options" class="uniDataPickerStyle"></uni-data-picker>
								</view>
								<view v-if="itemC.type==='TEXTAREA'">
									<up-textarea v-model="form[itemC.name]" border="none" input-align="right" fontSize="13px"
										:placeholder="itemC.placeholder" style="width: 200px;" count />
								</view>
								<view v-if="itemC.type==='DATE'">
									<uni-datetime-picker v-model="form[itemC.name]" :border="false" />
								</view>
							</template>
						</up-form-item>
					</template>
				</template>

			</template>

		</up-form>
		<!-- <view>
      <up-button @click="submit" type="primary">提交</up-button>
    </view> -->
	</view>
</template>
<script setup>
	import { reactive, ref, computed, onMounted, watch, toRaw } from 'vue'
	const props = defineProps({
		formPros: {
			type: Array,
			default: () => [],
		},
	})




	// 响应式表单数据
	const form = ref({})
	//表单渲染数据
	const formFields = ref([])
	/**
	 * @param {Object} itN 选中的数据
	 * @param {Object} index 最外层下标
	 * @param {Object} index1 最内层下表
	 * @param {Object} index2 渲染 children 的下标
	 *
	 *
	 */

	const changePicker = (val, itm) => {
		console.log('change', val, itm)
		form.value[itm] = val.detail.value.map(item => item.text).join('/')
	}
	const changeSelect = (val, itm) => {
		console.log('change', val, itm, )

		form.value[itm.name] = [itm.options.options.find(item => item.value === val).text, val]
	}
	const typeParams = type => {
		let flag = ''
		switch (type) {
			case 'NUMBER':
				flag = 'number'
				break
			case 'FILE':
				flag = 'array'
				break
			default:
				flag = 'string'
				break
		}
		return flag
	}
	const blurFun = (itN, index, index1, index2, value) => {
		// console.log(itN, index, index1, index2, value, 'itN,itC, numitN,itC, numitN,itC, numitN,itC, num')
		let mapItem = toRaw(formFields.value[index].nestField[0])
		let mapData = toRaw(formFields.value[index].nestField)
		let mapDataLast = mapData[mapData.length - 1]
		let mapDataLastNum = mapDataLast[0].order


		let mapForm = toRaw(form.value)
		let deepmapData = JSON.parse(JSON.stringify(mapData))


		function dealData(dealmapData, dealobj) {
			//判断字符串是否是纯数字
			function isPureNumber(str) {
				return /^-?\d+(\.\d+)?$/.test(str)
			}
			dealmapData.forEach((item, index) => {
				item.forEach((item1, index1) => {
					item1.value = dealobj[item1.name]
					item1.name = isPureNumber(item1.name.charAt(item1.name.length - 1)) ?
						item1.name.slice(0, item1.name.length - 1) :
						item1.name
				})
			})
			let arr = dealmapData.map(group => {
				let obj1 = {}
				group.forEach(item => {
					obj1[item.name] = item.value
				})
				return obj1
			})
			return arr
		}

		form.value[formFields.value[index].name] = dealData(deepmapData, mapForm)

		// 判断是否是最后一条数据的最后一个
		if (mapData.length - 1 === index2 && itN.length - 1 === index1) {
			formFields.value[index].nestField.push(mapItem.map((t, i) => {
				return {
					...t,
					order: mapDataLastNum + 1,
					name: t.name + (mapDataLastNum + 1),
					placeholder: t.placeholder + (mapDataLastNum + 1),
					required: false
				}
			}))
			let refMapDataAfter = formFields.value[index].nestField
			let mapItemAfter = toRaw(formFields.value[index].nestField[0])
			let mapDataAfter = toRaw(formFields.value[index].nestField)
			let mapDataLastAfter = mapDataAfter[mapDataAfter.length - 1]
			// let refMapData = formFields.value[index].nestField
			// 表单渲染 数组最后一项之前的都设置成true
			let newMapDataAfter = refMapDataAfter.slice(0, refMapDataAfter.length - 1)
			newMapDataAfter.forEach((t, i) => {
				t.forEach((t1, i1) => {
					t1.required = true
				})
			})
			//校验规则 数组最后一项之前的都设置成true
			let newFilterData = []
			newMapDataAfter.forEach((t, i) => {
				newFilterData = newFilterData.concat(t)
			})
			newFilterData.forEach((t, i) => {
				if (t.validation.pattern) {
					rules.value[t.name] = [{
							required: true,
							message: t.validation.message,
							trigger: ['blur', 'change'],
						},
						{
							pattern: t.validation.pattern,
							// 正则检验前先将值转为字符串
							transform(value) {
								return String(value)
							},
							message: t.validation.message,
						},
					]
				} else {
					rules.value[t.name] = {
						type: typeParams(t.type),
						required: true,
						message: t.validation.message,
						trigger: ['blur', 'change'],
					}
				}
			})
			// 数组的最后一项校验规则required为false
			// console.log(mapDataLastAfter, 'mapDataLastAftermapDataLastAftermapDataLastAfter')
			// return
			mapDataLastAfter.forEach((t, i) => {
				if (t.validation.pattern) {
					rules.value[t.name] = [{
							required: false,
							message: t.validation.message,
							trigger: ['blur', 'change'],
						},
						{
							pattern: t.validation.pattern,
							// 正则检验前先将值转为字符串
							transform(value) {
								return String(value)
							},
							message: t.validation.message,
						},
					]
				} else {
					rules.value[t.name] = {
						type: typeParams(t.type),
						required: false,
						message: t.validation.message,
						trigger: ['blur', 'change'],
					}
				}
			})
		}
	}

	// 校验规则
	const rules = computed(() => {
		let obj = {}



		console.log('我执行了！~~~')
		formFields.value.forEach((item, index) => {
			if (item.validation.pattern) {
				obj[item.name] = [{
						required: item.validation.required,
						message: item.validation.message,
						trigger: ['blur', 'change'],
					},
					{
						pattern: item.validation.pattern,
						// 正则检验前先将值转为字符串
						transform(value) {
							return String(value)
						},
						message: item.validation.message,
					},
				]
			} else {
				//如果类型是NESTTEXT 循环嵌套 加上rules
				if (item.type === 'NESTTEXT') {
					let nestTextArr = toRaw(formFields.value).filter((item, index) => {
						return item.type === 'NESTTEXT'
					})
					console.log(nestTextArr, 'nestTextArrnestTextArr')
					let newArr = []
					nestTextArr.forEach((item, index) => {
						console.log(item.nestField[0], 'item.nestField[0]')
						newArr = newArr.concat(item.nestField[0])
					})
					console.log(newArr, 'newArrnewArrnewArr')
					newArr.forEach((item1, index1) => {
						if (item1.validation.pattern) {
							obj[item1.name] = [{
									required: item1.validation.required,
									message: item1.validation.message,
									trigger: ['blur', 'change'],
								},
								{
									pattern: item1.validation.pattern,
									// 正则检验前先将值转为字符串
									transform(value) {
										return String(value)
									},
									message: item1.validation.message,
								},
							]
						} else {
							obj[item1.name] = {
								type: typeParams(item1.type),
								required: item1.validation.required,
								message: item1.validation.message,
								trigger: ['blur', 'change'],
							}
						}
					})
				} else {
					obj[item.name] = {
						type: typeParams(item.type),
						required: item.validation.required,
						message: item.validation.message,
						trigger: ['blur', 'change'],
					}
				}

			}

		})
		return obj

	})
	watch(
		() => props.formPros,
		(newVal, oldVal) => {
			let newobj = {}
			newVal.forEach((item, index) => {
				if (item.type === 'FILE') {
					newobj[item.name] = []
				} else {
					newobj[item.name] = ''
				}
			})
			const deepData = toRaw(newVal)
			const deepData1 = JSON.parse(JSON.stringify(newVal))
			console.log(deepData, 'newValnewValnewVal')
			form.value = newobj
			console.log('我被监听了我被监听了我被监听了')
			formFields.value = deepData1
		}, { deep: true, },
	)
	onMounted(() => {})
	// const rules = {
	// 	complainant_name: {
	// 		required: true,
	// 		message: '请输入姓名',
	// 		trigger: ['blur', 'change'],
	// 	},
	// 	contact_phone: {
	// 		required: true,
	// 		message: '请选择时间',
	// 		trigger: ['blur', 'change'],
	// 	},
	// }

	// 表单引用
	const uFormRef = ref(null)

	// 提交方法
	async function submit() {
		const p = new Promise((resolve, reject) => {
			uFormRef.value
				.validate()
				.then(valid => {
					if (valid) {
						resolve(form.value)
						uni.$u.toast('校验通过')
					} else {
						uni.$u.toast('校验失败')
					}
				})
				.catch(() => {
					// 处理验证错误
					reject('校验失败')
					uni.$u.toast('校验失败')
				})
		})
		return p
	}
	defineExpose({ submit, })
</script>

<script>
	export default {
		/* 就是👇这句 记得加上 ❗️❗️*/
		options: { styleIsolation: 'shared' },
	}
</script>

<style scoped lang="scss">
	.dynamicForm {
		.submitBtn {
			position: fixed;
			bottom: 0;
			background-color: red;
			width: 95%;
			left: 50%;
			transform: translateX(-50%);
		}

		.uniDataSelectStyle {
			width: 400rpx;

			:deep(.uni-select) {
				border: none;
			}

			:deep(.uni-select__input-text) {
				text-align: right;
			}
		}

		.uniDataPickerStyle {
			width: 400rpx;

			::v-deep .input-value {
				border: none !important;
			}

			:deep(.selected-list) {
				justify-content: flex-end;
			}

			:deep(.selected-area) {
				justify-content: flex-end;
			}
		}

		.textareaStyle {
			width: 90%;
			margin: 0 auto;
			margin-top: 10px;

			:deep(.u-textarea__field) {
				font-size: 12px;
			}
		}

		.upTextarea {
			width: 300rpx;
		}
	}
</style>